package com.wangwen.wechatmp.controller;

import com.google.common.collect.Maps;
import com.wangwen.wechatmp.dao.ConfWxmpDao;
import com.wangwen.wechatmp.dao.UserInfoDao;
import com.wangwen.wechatmp.entity.ApiResponse;
import com.wangwen.wechatmp.exception.RuntimeCheck;
import com.wangwen.wechatmp.model.ConfWxmp;
import com.wangwen.wechatmp.model.UserInfo;

import com.wangwen.wechatmp.utils.SecuritySHA1Utils;
import com.wangwen.wechatmp.utils.WechatUtils;
import com.wangwen.wechatmp.wxpkg.config.WxMpConfiguration;

import io.swagger.annotations.*;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;
import java.util.*;


/**
 * @author wangwei
 * @description 使用微信体系会员
 * @date 2019/10/17
 */
@Api( tags="微信接口模块")
@RestController
@RequestMapping("/api/wechat/card")
public class WechatUserController {


    @Autowired
    private WechatUtils wechatUtils;

    @Autowired
    private ConfWxmpDao confWxmpDao;

    @Autowired
    private UserInfoDao userInfoDao;



    protected Logger logger = LoggerFactory.getLogger(getClass());

    @ApiOperation(value="获取JSSDK签名", notes = "获取JSSDK签名")
    @GetMapping("getJsApiSign")
    @ResponseBody
    public ApiResponse<Map<String,Object>> getJsApiSign(@RequestHeader("hotelid") @NotBlank(message = "业务ID不能为空")  Integer hotelId,String url){
        try {
            Map map = new HashMap();
            ConfWxmp confWxmp = confWxmpDao.findByBusId(hotelId);
            RuntimeCheck.ifNull(confWxmp,"该酒店信息未配置");
            final WxMpService wxMpService = WxMpConfiguration.getMpService(confWxmp.getAppId());
            String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
            String nonceStr = wechatUtils.getNoncestr();
            String ticket = wxMpService.getJsapiTicket();
            String params = "jsapi_ticket=" +ticket +
                    "&noncestr=" + nonceStr +
                    "&timestamp="+ timestamp +
                    "&url="+url;
            logger.info("----参数params---"+params);
            String sign = DigestUtils.shaHex(params);
            logger.info("----返回sign---"+sign);
            map.put("sign",sign);
            map.put("appId",confWxmp.getAppId());
            map.put("timestamp",timestamp);
            map.put("nonceStr",nonceStr);

            return ApiResponse.success(map);
        } catch (WxErrorException e) {
            logger.error("getJsApiSign error",e);
            e.printStackTrace();
            return ApiResponse.fail(new HashMap<>());
        }
    }

    @ApiOperation(value="获取api_ticket", notes = "微信卡券接口中使用的签名凭证api_ticket")
    @GetMapping("/apiTicket")
    public ApiResponse<String> getApiTicket(@RequestHeader("busId") @NotBlank(message = "业务ID不能为空")  Integer busId){
        try {
            WxMpService wxMpService = wechatUtils.getMpService(busId);
            String apiTicket = WxMpConfiguration.WxMpCardService(wxMpService).getCardApiTicket();
            return ApiResponse.success(apiTicket,"操作成功");
        } catch (WxErrorException e) {
            logger.error("获取apiTicket失败",e);
            e.printStackTrace();
            return ApiResponse.fail("获取apiTicket失败");
        }
    }

    @ApiOperation(value="通过code获取openId", notes = "通过code获取openId")
    @GetMapping("/getOpenid")
    public ApiResponse<String> getOpenid(@RequestHeader("hotelid") @NotBlank(message = "业务ID不能为空")  Integer hotelId,String code){
        String openId = wechatUtils.getOpenid(hotelId,code);
        if (openId == null){
            return ApiResponse.fail("操作失败！");
        }
        return ApiResponse.success(openId,"操作成功");
    }



    @ApiOperation(value="会员卡解密code", notes = "解密code")
    @ApiImplicitParam(name="code", value="加密的code",paramType = "path", required = true, dataType = "String")
    @GetMapping("/decryptCardCode/{code}")
    public ApiResponse<String> decryptCardCode(@PathVariable("code") String code,@RequestHeader("busId") @NotBlank(message = "业务ID不能为空")  Integer busId){
        String decryptCardCode = "";
        try {
            WxMpService wxMpService = wechatUtils.getMpService(busId);
            decryptCardCode = WxMpConfiguration.WxMpCardService(wxMpService).decryptCardCode(code);
        } catch (WxErrorException e) {
            e.printStackTrace();
            return ApiResponse.fail("解密code失败");
        }
        return ApiResponse.success(decryptCardCode);
    }
    @ApiOperation(value="签名，商户将接口列表中的参数按照指定方式进行签名,签名方式使用SHA1", notes = "")
    @GetMapping("/getSignature")
    public ApiResponse<Map<String,Object>> getSignature(@RequestHeader("hotelid") @NotBlank(message = "业务ID不能为空")  Integer busId,@RequestHeader("openid") @NotBlank(message = "openid")  String openid) throws Exception {
        Map<String,Object> map = Maps.newConcurrentMap();
        //通过业务ID找到相应的微信服务
        WxMpService wxMpService = wechatUtils.getMpService(busId);

        String apiTicket = WxMpConfiguration.WxMpCardService(wxMpService).getCardApiTicket();
        long timestamp = System.currentTimeMillis() / 1000;
        String non_str = wechatUtils.getNoncestr();
        ConfWxmp confWxmp = confWxmpDao.findByBusId(busId);
        String card_id = "";
        if(StringUtils.isNotEmpty(confWxmp.getCardId())){
            card_id = confWxmp.getCardId();
        }
        //查询用户信息，
        logger.info("用户openId:" + openid);
        UserInfo userInfo = userInfoDao.findByOpenId(openid);
        if(userInfo != null){

            map.put("userInfo",userInfo);
        }else{
            map.put("userInfo","");

        }

        String s = timestamp + apiTicket +  non_str + card_id ;
        ArrayList<String> list=new ArrayList<String>();
        list.add(non_str);
        list.add(String.valueOf(timestamp));
        list.add(apiTicket);
        list.add(card_id);

        Collections.sort(list);

        String signature = SecuritySHA1Utils.shaEncode(list.get(0)+list.get(1)+list.get(2)+list.get(3));

        logger.info("签名sign:" + signature);
        map.put("apiTicket",apiTicket);
        map.put("timestamp",timestamp);
        map.put("nonStr",non_str);
        map.put("signature",signature);
        map.put("cardId",card_id);
        map.put("openId",openid);
        return ApiResponse.success(map);
    }

}
